#include "ray.h"
#include "line.h"
#include "utilities.h"

GeometryUtilities::Ray::Ray()
: mStart(0.0,0.0), mDir(0.0,0.0){}

GeometryUtilities::Ray::Ray(const GeometryUtilities::Point &start,
                            const GeometryUtilities::Point &dir)
: mStart(start), mDir(dir) {}

const GeometryUtilities::Point& GeometryUtilities::Ray::start() const
{
  return mStart;
}

GeometryUtilities::Point& GeometryUtilities::Ray::start()
{
  return mStart;
}

const GeometryUtilities::Point& GeometryUtilities::Ray::direction() const
{
  return mDir;
}

GeometryUtilities::Point& GeometryUtilities::Ray::direction()
{
  return mDir;
}

bool GeometryUtilities::Ray::operator==(const GeometryUtilities::Ray& rhs) const
{
  return mDir == rhs.direction() && mStart == rhs.start();
}

bool GeometryUtilities::Ray::isPointOn(const GeometryUtilities::Point& p) const
{
  GeometryUtilities::Line line(mStart, mStart+(mDir*10));
  if (line.isVertical())
  {
    return (Utilities::floatEquality(p.x(), line.xIntercept()) &&
            ((mDir.y() > 0 && p.y() >= mStart.y()) ||
             (mDir.y() < 0 && p.y() <= mStart.y())));
  }
  else
  {
    return (Utilities::floatEquality(p.y(), line.slope()*p.x()+line.yIntercept()) &&
            ((mDir.x() > 0 && p.x() >= mStart.x()) ||
             (mDir.x() < 0 && p.x() <= mStart.x())));
  }
}
